package com.googlecode.continuity.core.server.hibernate;

import com.googlecode.continuity.core.client.Enum;
import net.sf.beanlib.PropertyInfo;
import net.sf.beanlib.spi.BeanTransformerSpi;
import net.sf.beanlib.spi.CustomBeanTransformerSpi;
import net.sf.hibernate4gwt.core.beanlib.TimestampCustomTransformer;

/**
 * CustomTransformerTimestampEnum, transforms both classes inheriting {@link Enum} and timestamps, the latter using the
 * {@link net.sf.hibernate4gwt.core.beanlib.TimestampCustomTransformer}.
 *
 * @author Peter Schmitt <aragos@aragos.de>
 */
public class CustomTransformerTimestampEnum implements CustomBeanTransformerSpi {
  private TimestampCustomTransformer timestampTransformer;

  /**
   * Constructs a new CustomTransformerTimestampEnum using a
   * {@link net.sf.hibernate4gwt.core.beanlib.TimestampCustomTransformer}.
   *
   * @param beanTransformer bean transformer to use
   */
  public CustomTransformerTimestampEnum(final BeanTransformerSpi beanTransformer) {
    timestampTransformer = new TimestampCustomTransformer(beanTransformer);
  }

  /**
   * Returns true if this custom transformer can handle the given object and class.
   *
   * @param from    original object to be transformed
   * @param toClass class into which the object is to be transformed
   * @param info    further information
   * @return true if the given object can be handled, false otherwise
   */
  public <T> boolean isTransformable(Object from, Class<T> toClass, PropertyInfo info) {
    return timestampTransformer.isTransformable(from, toClass, info) || Enum.class.isAssignableFrom(toClass);
  }

  /**
   * Transforms the given object.
   *
   * @param in      original object
   * @param toClass target class
   * @param info    further information
   * @return transformed object
   */
  @SuppressWarnings("unchecked")
  public <T> T transform(Object in, Class<T> toClass, PropertyInfo info) {
    if (Enum.class.isAssignableFrom(toClass)) {
      return (T) in;
    }
    return timestampTransformer.transform(in, toClass,  info);
  }
}
